use anyhow::Ok;
use rand::seq::{IndexedRandom, SliceRandom};

use crate::cli::genpass::GenPassOpts;  // 导入结构体  为什么会是  crate::  因为在 lib.rs 里 pub use 出去了

// 加不加 static  都行，   如 &'static [u8],   CONST 能推断出是全局的
const UPPER :&[u8] = b"ABCDEFGHJKLMNPQRSTUVWXYZ"; // 去掉了 I 和 O 
const LOWER :&[u8] = b"abcdefghijkmnopqrstuvwxyz"; // 去掉了 l
const NUMBER: &[u8] = b"123456789"; // 去掉了 0  // 避免和 O 混淆
const SYMBOL: &[u8] = b"!@#$%^&*";

pub fn process_genpass(
   genPassOpts: &GenPassOpts
) -> anyhow::Result<()> {

    // length: u8 
    // upper:bool,
    // lower:bool,
    // number:bool,
    // symbol:bool,

    let length: u8 = genPassOpts.length;
    let upper:bool = genPassOpts.uppercase;
    let lower:bool = genPassOpts.lowercase;
    let number:bool = genPassOpts.number;
    let symbol:bool = genPassOpts.symbol;

    // 这里是生成密码的逻辑
    println!("Generating password...");
    let mut rng = rand::rng();
    let mut password = String::new();
    let mut chars : Vec<u8>  = Vec::new();

    if upper {
        chars.extend(UPPER);
        //chars.extent_from_slice(b"abcdefghijkmnopqrstuvwxyz");
    
      //  password.push(*UPPER.choose(&mut rng).expect("UPPER won't be empty in this context") as char);
    }
    if lower {
        chars.extend(LOWER);  
    }

    if number {
        chars.extend(NUMBER);
    }   
    if symbol {
        chars.extend(SYMBOL);
    }   

    
    for _ in 0..length {
        // let idx = rng.gen_range(0..chars.len());

        // password.push(chars[idx] as char);
        let c = chars.choose(&mut rng)
        .expect("chars won't be empty in this context");
        password.push(*c as char);
    }

    // 展示密码强度 
    let estimate = zxcvbn::zxcvbn(&password, &[]);
    eprintln!("Password strength: {} . ", estimate.score());  // eprint   当写入文本中， 是不写入的

    println!("{}", password);
    Ok(())
}